package falcon.script;

public final class FalconLangAst {

	public static final int UNKNOWN = 0;
	
	public static final int SEQ = 1;
	public static final int RET = 2;
	
	public static final int ASSIGN = 3;
	public static final int PASS = 4;
	
	public static final int INVOKE_FUNC = 5;
	public static final int INVOKE_FLOW = 6;
	public static final int INVOKE_SYS = 7;
	
	public static final int CONDITION_IF = 8;
	public static final int CONDITION_ELIF = 9;
	public static final int CONDITION_ELSE = 10;
	public static final int CONDITION_END = 11;
	
	public static final int LOGIC_AND = 12;
	public static final int LOGIC_OR = 13;
	
	public static final int COMPARE_EQ = 14;
	public static final int COMPARE_NE = 15;
	public static final int COMPARE_GT = 16;
	public static final int COMPARE_GE = 17;
	public static final int COMPARE_LT = 18;
	public static final int COMPARE_LE = 19;
	
	public static final int OPERATOR_JOIN = 20;
	public static final int OPERATOR_ADD = 21;
	public static final int OPERATOR_SUB = 22;
	public static final int OPERATOR_MUL = 23;
	public static final int OPERATOR_DIV = 24;
	public static final int OPERATOR_MOD = 25;
	
	public static final int VALUE_CONST = 26;
	public static final int VALUE_TMP = 27;
	public static final int VALUE_VAR = 28;
	public static final int VALUE_ARG = 29;
	
	public int type;
	public FalconLangToken token;
	public FalconLangAst child1;
	public FalconLangAst child2;
	
	public FalconLangAst(int type) {
		this.type = type;
		this.token = null;
		this.child1 = null;
		this.child2 = null;
	}
	
	public FalconLangAst() {
		this(UNKNOWN);
	}
	
	public static void copy(FalconLangAst src, FalconLangAst dst) {
		dst.type = src.type;
		dst.token = src.token;
		dst.child1 = src.child1;
		dst.child2 = src.child2;
	}

	@Override
	public String toString() {
		if (this.type == SEQ) {
			return "SEQ";
		} else if (this.type == RET) {
			return String.format("RET(%s)", this.token.value);
		} else if (this.type == ASSIGN) {
			return "ASSIGN";
		} else if (this.type == PASS) {
			return "PASS";
		} else if (this.type == INVOKE_FUNC) {
			return String.format("FUNC(%s)", this.token.value);
		} else if (this.type == INVOKE_FLOW) {
			return String.format("FLOW(%s)", this.token.value);
		} else if (this.type == INVOKE_SYS) {
			return String.format("SYS(%s)", this.token.value);
		} else if (this.type == CONDITION_IF) {
			return "IF";
		} else if (this.type == CONDITION_ELIF) {
			return "ELIF";
		} else if (this.type == CONDITION_ELSE) {
			return "ELSE";
		} else if (this.type == CONDITION_END) {
			return "END";
		} else if (this.type == LOGIC_AND) {
			return "AND";
		} else if (this.type == LOGIC_OR) {
			return "OR";
		} else if (this.type == COMPARE_EQ) {
			return "EQ";
		} else if (this.type == COMPARE_NE) {
			return "NE";
		} else if (this.type == COMPARE_GT) {
			return "GT";
		} else if (this.type == COMPARE_GE) {
			return "GE";
		} else if (this.type == COMPARE_LT) {
			return "LT";
		} else if (this.type == COMPARE_LE) {
			return "LE";
		} else if (this.type == OPERATOR_JOIN) {
			return "JOIN";
		} else if (this.type == OPERATOR_ADD) {
			return "ADD";
		} else if (this.type == OPERATOR_SUB) {
			return "SUB";
		} else if (this.type == OPERATOR_MUL) {
			return "MUL";
		} else if (this.type == OPERATOR_DIV) {
			return "DIV";
		} else if (this.type == OPERATOR_MOD) {
			return "MOD";
		} else if (this.type == VALUE_CONST) {
			return String.format("C\"%s\"", this.token.value);
		} else if (this.type == VALUE_TMP) {
			return String.format("T[%s]", this.token.value);
		} else if (this.type == VALUE_VAR) {
			return String.format("V{%s}", this.token.value);
		} else if (this.type == VALUE_ARG) {
			return String.format("A{%s}", this.token.value);
		}
		return "UNKWN";
	}
}
